/**
 * 公司：xxx有限公司
 * 版权：xxx2020
 * 描述：基于primeNG的Table组件对象封装
 * 作者：oyjl
 * 时间：2020-03-05 08:50:26
 */

import { MenuItem } from 'primeng/api';

/**
 * 描述：基于primeNG的Table组件对象
 * 作者：oyjl
 * 时间：2020-03-05 09:38:06
 */
export class RTable {
  prop: RTableProp; // 表格属性配置
  event: RTableEvent; // 表格事件回调
  paginator: RTablePaginator; // 表格分页属性
  constructor(data: any = {}) {
    this.prop = new RTableProp(data.prop);
    this.event = new RTableEvent(data.event);
    this.paginator = new RTablePaginator(data.paginator);
  }
}

/**
 * 描述：Table组件对象属性，排序模式仅仅支持单列排序
 * 作者：oyjl
 * 时间：2020-03-05 09:40:06
 */
export class RTableProp {
  columns: Array<RTableColumns>; // 动态列的对象数组
  value: Array<any>; // 要显示的静态对象数组，如果通过接口请求数据将替换该静态数据
  customSort?: boolean; // 是否启用自定义排序, 默认不启用
  sortFunction?: (argv) => void; // 自定义排序的方法，仅仅在自定义排序为true有效
  selectionMode?: string; // 选中的行模式，single（单选）、multiple（多选）
  selection?: any; // 选中的行数据
  lazy?: boolean; // 是否采用懒加载方式, 默认不启用
  scrollable?: boolean; // 是否使用滚动条, 默认不启用
  scrollHeight?: string; // 滚动视口高度
  resizableColumns?: boolean; // 是否可以调整列的宽度, 默认不启用
  loading?: boolean; // 是否显示程序正在加载, 默认不启用
  autoLayout?: boolean; // 是否自动布局，列的宽度根据内容自动缩放, 默认启用
  paginator?: boolean; // 是否启用分页, 采用表格外部分页方式, 默认启用
  paginatorPosition?: string; // 分页组件位置，bottom(底部，系统页面底部，默认设置)、both(中间，紧挨着表格数据下)
  dataConfig?: RDataConfig; // 表格中的数据项位置及请求成功状态配置，默认{key:'data',status: 'status', value: 200}
  constructor(data: any = {}) {
    this.columns = data.columns;
    this.value = data.value || [];
    this.customSort = data.customSort;
    this.sortFunction = data.sortFunction || new Function();
    this.selectionMode = data.selectionMode;
    this.selection = data.selection;
    this.lazy = data.lazy;
    this.scrollable = data.scrollable || false;
    this.scrollHeight = data.scrollHeight || '1200px';
    this.resizableColumns = data.resizableColumns;
    this.loading = data.loading;
    this.autoLayout = data.autoLayout || true;
    this.paginator = data.paginator || true;
    this.paginatorPosition = data.paginatorPosition || 'bottom';
    this.dataConfig = data.dataConfig || { key: 'pageModel.rows', status: 'operateSuccess', value: true };
  }
}

/**
 * 描述：Table组件对象属性值
 * 作者：oyjl
 * 时间：2020-03-05 09:44:50
 */
export class RTableEvent {
  onRowSelect?: (argv) => void; // 选中行回调
  onRowUnselect?: (argv) => void; // 取消选中行回调
  onSort?: (argv) => void; // 排序发生时回调
  onPage?: (argv) => void; // 分页发生时调用
  constructor(data: any = {}) {
    this.onRowSelect = data.onRowSelect || new Function();
    this.onRowUnselect = data.onRowUnselect || new Function();
    this.onSort = data.onSort || new Function();
    this.onPage = data.onPage || new Function();
  }
}

/**
 * 描述：Table组件对象属性值分页
 * 作者：oyjl
 * 时间：2020-03-05 09:42:41
 */
export class RTablePaginator {
  pageNo: number; // 当前页
  pageSize: number; // 分页行数
  first: number; // 要显示的第一行的索引
  total: number; // 总记录数
  pageLinkSize?: number; // 页面链接数
  rowsPerPageOptions?: Array<any>; // 分页的下拉列表
  pageCount?: number; // 总页数
  constructor(data: any = {}) {
    this.pageNo = data.pageNo || 1;
    this.pageSize = data.pageSize || 15;
    this.first = (data.pageSize * (data.pageNo - 1)) || 0;
    this.total = data.total || 0;
    this.pageLinkSize = data.pageLinkSize || 5;
    this.rowsPerPageOptions = data.rowsPerPageOptions || [10, 15, 25, 35, 50];
    this.pageCount = Math.ceil(data.total / data.pageSize) || 1;
  }
}

/**
 * 描述：Table组件分页参数前后端映射
 * 作者：oyjl
 * 时间：2020-03-14 00:24:38
 */
export class RPaginatorArgv {
  key: string;
  pageNo: string;
  pageSize: string;
  total: string;
  firstIndex: number;
  constructor(data: any = {}) {
    this.key = data.key || 'pageInfo';
    this.pageNo = data.pageNo || 'pageIndex';
    this.pageSize = data.pageSize || 'pageSize';
    this.total = data.total || 'pageTotal';
    this.firstIndex = data.firstIndex || 1;
  }
}

/**
 * 描述：Table组件动态表格列配置
 * 作者：oyjl
 * 时间：2020-03-05 11:00:41
 */
export interface RTableColumns {
  header: string; // 表头标题，用于展示
  field: string; // 表格列数据字段,field + 'Style'字段表示该字段的样式
  buttonAuthority?: string; // 操作权限，如果为空即不控制
  isSort?: boolean; // 该列是否支持排序
  type?: string; // 字段的类型：index:序号，text: 文本，ck：多选，rd：单选，sw：开关(仅仅接收boolean型)，dict: 字典转换，operator：操作，date: 时间，默认为text,文本类型
  fieldClass?: object; // 特性配置自定义的样式，标准格式{class: xxxx,symbol: xxx,value:xxx}, 特别说明symbol为判断符号仅仅支持>、<、=、>=、<=，value为比较值
  operator?: Array<RTableOperator>; // 操作的字段数组，配置文本显示以及点击回调,仅仅在type=operator有效
  width?: string; // 表格列宽度定义
  fieldOpEvt?: (event, data, rowConfig) => void; // 字段点击回调函数，包括sw的onChange事件，传参为当前点击组件event,当前行数据,当前行配置
  format?: string; // 时间格式化
  langKey?: string; // 国际化key值
  initEvt?: (argv, rowConfig) => void; // 初始数据处理函数，传参为当前行数据,当前行配置
  style?: object; // 单列样式
  dictType?: string; // 字典key值,
  htmlString: string; // html片段，支持自定义html片段
}

/**
 * 描述：操作配置
 * 作者：oyjl
 * 时间：2020-03-05 12:20:52
 */
export interface RTableOperator {
  type: string; // 操作类型（目前2类,text:单行文本按钮，splitButton: 带下拉数据按钮）
  text: string; // 文本展示
  buttonAuthority?: string; // 操作权限，如果为空即不控制
  inlineClass?: string; // 内联样式
  hiddenField?: string; // 隐藏字段，根据配置的隐藏字段是否为true来控制当前操作是否隐藏，例如：配置为'dictDelete'，则当行数据中dictDelete为true时该操作隐藏
  clickEvt?: () => void; // 点击回调方法
  options: MenuItem[]; // splitButton下拉操作项列表
}

/**
 * 描述：数据请求配置
 * 作者：oyjl
 * 时间：2020-03-17 20:53:46
 */
export interface RQuest {
  url: string; // 请求后端数据的url
  req?: any; // 请求条件
}

/**
 * 描述：表格数据及成功状态配置
 * 作者：oyjl
 * 时间：2020-04-22 09:17:21
 */
export interface RDataConfig {
  key: string; // 后端数据
  status: string; // 后端状态字段
  value: any; // 后端成功状态值
}

/**
 * 描述：字段类型：index:序号，text: 文本，ck：多选，rd：单选，sw：开关(仅仅接收boolean型)，dict: 字典转换，operator：操作，date: 时间，默认为text
 * 作者：oyjl
 * 时间：2021-07-16 15:21:55
 */
export enum TABLE_TYPE {
  index = 'index', // 序号
  text = 'text', // 文本
  ck = 'ck', // 多选
  rd = 'rd', // 单选
  sw = 'sw', // 开关(仅仅接收boolean型)
  dict = 'dict', // 字典转换
  date = 'date', // 时间
  htmlString = 'htmlString', // 自定义html片段
  operator = 'operator', // 操作
  splitButton = 'splitButton', // 带下拉数据按钮
}
